from django.dispatch import receiver
from django.shortcuts import render

from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.conf import settings
#函数式
from rest_framework.decorators import api_view
from rest_framework.permissions import IsAuthenticated
#类视图
from rest_framework.views import APIView
#通用类视图（使用最多，最方便）
from rest_framework import generics
#视图集
from rest_framework import viewsets

from rest_framework.response import Response
from rest_framework import status
from .models import Course
from .serializer import CourseSerializer
from rest_framework.authtoken.models import Token
from .permissinos import IsOwerReadOnly


@receiver(post_save,sender=settings.AUTH_USER_MODEL)#Django信号机制
def generate_token(sender,instance=None,created=False,**kwargs):
    """
    创建用户时自动生成Token
    :param sender:
    :param instance:
    :param created:
    :param kwargs:
    :return:
    """
    if created:
        Token.objects.create(user=instance)

# Create your views here.
"""1.函数式编程 Function Based View"""


@api_view(["GET", "POST"])
def course_list(request):
    """
    获取所有课程信息或者新增课程
    :param request:
    :return:
    """
    if request.method == "GET":
        # instance=实例对象（这里是所有课程）  many=True（序列化多个对象）
        s = CourseSerializer(instance=Course.objects.all(), many=True)
        # data=指定的数据.data          status=指定的状态码
        return Response(data=s.data, status=status.HTTP_200_OK)

    elif request.method == "POST":
        s = CourseSerializer(data=request.data)  # 部分更新用partial=True属性
        # 反序列化校验
        if s.is_valid():
            s.save(teacher=request.user)
            return Response(data=s.data, status=status.HTTP_201_CREATED)
        return Response(s.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(["GET", "PUT", "DELETE"])
def course_detail(request, pk):
    """
    获取、更新、删除一个课程
    :param request:
    :param pk:
    :return:
    """
    try:
        course = Course.objects.get(pk=pk)
    except Course.DoesNotExist:
        return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)
    else:
        if request.method == "GET":
            s = CourseSerializer(instance=course)
            return Response(data=s.data, status=status.HTTP_200_OK)

        elif request.method == "PUT":
            s = CourseSerializer(instance=course, data=request.data)
            if s.is_valid():
                s.save()
                return Response(s.data, status=status.HTTP_200_OK)

        elif request.method == "DELETE":
            course.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)


"""2、类视图  CLass Based View"""

class CourseList(APIView):
    #APIView里面的request不是原生的，而是APIView里面的dicpath重新重现创建的request
    def get(self, request):
        """

        :param request:
        :return:
        """
        queryset = Course.objects.all()
        s = CourseSerializer(instance=queryset, many=True)#序列化用instance，序列化是将后端数据->json数据给前端发
        return Response(s.data, status=status.HTTP_200_OK)

    def post(self, request):
        """

        :param request:
        :return:
        """
        s = CourseSerializer(data=request.data)#反序列化用data，反序列化是将前端给的json数据->后端需要的数据
        if s.is_valid():#利用is_valid()进行数据的校验，返回一个布尔值
            s.save(teacher=self.request.user)
            print(type(request.data), type(s.data))
            return Response(data=s.data, status=status.HTTP_201_CREATED)
        return Response(s.errors, status=status.HTTP_400_BAD_REQUEST)


class CourseDetail(APIView):
    @staticmethod
    def get_object(pk):
        """

        :param pk:
        :return:
        """
        try:
            return Course.objects.get(pk=pk)
        except Course.DoesNotExist:
            return

    def get(self, request, pk):
        """
        :param request:
        :param pk:
        :return:
        """
        obj = self.get_object(pk=pk)
        if not obj:
            return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)
        s = CourseSerializer(instance=obj)
        return Response(s.data, status=status.HTTP_200_OK)

    def put(self, request, pk):
        """
        :param request:
        :param pk:
        :return:
        """
        obj = self.get_object(pk=pk)
        if not obj:
            return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)
        s = CourseSerializer(instance=obj, data=request.data)
        if s.is_valid():
            s.save()
            return Response(data=s.data, status=status.HTTP_200_OK)
        return Response(s.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        """
        :param request:
        :param pk:
        :return:
        """
        obj = self.get_object(pk=pk)
        if not obj:
            return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)



"""3、通用类视图 Generic Class Based View"""


class GCourseList(generics.ListCreateAPIView):
    queryset = Course.objects.all()
    serializer_class = CourseSerializer

    def perform_create(self, serializer):
        serializer.save(teacher=self.request.user)

class GCourseDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Course.objects.all()
    serializer_class = CourseSerializer
    #权限：只要对象的所有者才能修改
    permission_classes = (IsAuthenticated,IsOwerReadOnly)


"""4、视图集  viewsets"""
class CourseViewSet(viewsets.ModelViewSet):
    queryset = Course.objects.all()
    serializer_class = CourseSerializer

    def perform_create(self, serializer):
        serializer.save(teacher=self.request.user)





